﻿using System;
using System.IO;
using System.Runtime.InteropServices;




public class LPV_CASH_DRAWER
{

    // Structure and API declarions:

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]

    public class DOCINFOA
    {

        [MarshalAs(UnmanagedType.LPStr)]
        public string pDocName;

        [MarshalAs(UnmanagedType.LPStr)]
        public string pOutputFile;

        [MarshalAs(UnmanagedType.LPStr)]
        public string pDataType;

    }

    [DllImport("winspool.Drv", EntryPoint = "OpenPrinterA", SetLastError = true,
    CharSet = CharSet.Ansi, ExactSpelling = true,
    CallingConvention = CallingConvention.StdCall)]

    public static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)]
string szPrinter, out IntPtr hPrinter, long pd);

    [DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true,
    ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]

    public static extern bool ClosePrinter(IntPtr hPrinter);

    [DllImport("winspool.Drv", EntryPoint = "StartDocPrinterA", SetLastError = true,
    CharSet = CharSet.Ansi, ExactSpelling = true,
    CallingConvention = CallingConvention.StdCall)]

    public static extern bool StartDocPrinter(IntPtr hPrinter, Int32 level,
    [In, MarshalAs(UnmanagedType.LPStruct)] DOCINFOA di);

    [DllImport("winspool.Drv", EntryPoint = "EndDocPrinter", SetLastError = true,
    ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]

    public static extern bool EndDocPrinter(IntPtr hPrinter);

    [DllImport("winspool.Drv", EntryPoint = "StartPagePrinter", SetLastError = true,
    ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]

    public static extern bool StartPagePrinter(IntPtr hPrinter);

    [DllImport("winspool.Drv", EntryPoint = "EndPagePrinter", SetLastError = true,
    ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]

    public static extern bool EndPagePrinter(IntPtr hPrinter);

    [DllImport("winspool.Drv", EntryPoint = "WritePrinter", SetLastError = true,
    ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]

    public static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes, Int32
    dwCount, out Int32 dwWritten);

    [DllImport("kernel32.dll", EntryPoint = "GetLastError", SetLastError = false,
    ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]

    public static extern Int32 GetLastError();

    public static bool SendBytesToPrinter(string szPrinterName, IntPtr pBytes,
    Int32 dwCount)
    {

        Int32 dwError = 0, dwWritten = 0;

        IntPtr hPrinter = new IntPtr(0);

        DOCINFOA di = new DOCINFOA();

        bool bSuccess = false; // Assume failure unless you specifically succeed.

        di.pDocName = "";// "My C#.NET RAW Document";

        di.pDataType = "RAW";

        if (OpenPrinter(szPrinterName, out hPrinter, 0))
        {

            if (StartDocPrinter(hPrinter, 1, di))
            {

                if (StartPagePrinter(hPrinter))
                {

                    bSuccess = WritePrinter(hPrinter, pBytes, dwCount, out dwWritten);

                    EndPagePrinter(hPrinter);

                }

                EndDocPrinter(hPrinter);

            }

            ClosePrinter(hPrinter);

        }

        if (bSuccess == false)
        {

            dwError = GetLastError();

        }

        return bSuccess;

    }

    public static bool SendFileToPrinter(string szPrinterName, string
    szFileName)
    {

        FileStream fs = new FileStream(szFileName, FileMode.Open);

        BinaryReader br = new BinaryReader(fs);

        Byte[] bytes = new Byte[fs.Length];

        bool bSuccess = false;

        IntPtr pUnmanagedBytes = new IntPtr(0);

        int nLength;

        nLength = Convert.ToInt32(fs.Length);

        bytes = br.ReadBytes(nLength);

        pUnmanagedBytes = Marshal.AllocCoTaskMem(nLength);

        Marshal.Copy(bytes, 0, pUnmanagedBytes, nLength);

        bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, nLength);

        Marshal.FreeCoTaskMem(pUnmanagedBytes);

        return bSuccess;

    }

    /// <summary>
    /// Hàm in từ chuỗi truyền vào
    /// </summary>
    /// <param name="szPrinterName">Tên máy in</param>
    /// <param name="szString">Chuỗi cần in</param>
    /// <returns>true : thành công; False : thất bại</returns>
    public static bool SendStringToPrinter(string szPrinterName, string
    szString)
    {

        IntPtr pBytes;

        Int32 dwCount;

        dwCount = szString.Length;

        pBytes = Marshal.StringToCoTaskMemAnsi(szString);

        SendBytesToPrinter(szPrinterName, pBytes, dwCount);

        Marshal.FreeCoTaskMem(pBytes);



        return true;

    }

    /// <summary>
    /// Hàm mở két
    /// </summary>
    public static void OpenCashDrawer(string PrinterName)
    {

        //byte[] codeOpenCashDrawer = new byte[] { 27, 112, 48, 55, 121 };
        byte[] codeOpenCashDrawer = new byte[] { 27, 112, 0, 25, 250 };

        IntPtr pUnmanagedBytes = new IntPtr(0);
        pUnmanagedBytes = Marshal.AllocCoTaskMem(5);
        Marshal.Copy(codeOpenCashDrawer, 0, pUnmanagedBytes, 5);
        LPV_CASH_DRAWER.SendBytesToPrinter(PrinterName, pUnmanagedBytes, 5);
        Marshal.FreeCoTaskMem(pUnmanagedBytes);
    }

}

